package org.example.mall.admin.common.es;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author hzq
 * @date 2022/1/16 14:42
 */
public class EsPageUtil {

    /**
     * 设置高亮字段
     *
     * @param searchSourceBuilder 搜索源工厂
     * @param fields              字段列表
     */
    public static void setHighlightField(SearchSourceBuilder searchSourceBuilder, String... fields) {
        if (fields == null || fields.length == 0)
            return;
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .preTags("<span style='color:red;font-weight:bold;'>").requireFieldMatch(false).postTags("</span>");
        for (String field : fields) {
            highlightBuilder.field(field);
        }
        searchSourceBuilder.highlighter(highlightBuilder);
    }

    /**
     * 设置分页参数
     *
     * @param searchSourceBuilder 搜索源工厂
     * @param page                分页参数
     */
    public static void setPageParams(SearchSourceBuilder searchSourceBuilder, Page page) {
        searchSourceBuilder.from(Integer.parseInt(String.valueOf(((page.getCurrent() - 1) * page.getSize()))));
        searchSourceBuilder.size(Integer.parseInt(String.valueOf(page.getSize())));
    }

    /**
     * 封装分页结果
     *
     * @param response 结果集
     * @param page     分页实体
     * @return 分页结果
     */
    public static IPage<Map<String, Object>> setPageResultMap(SearchResponse response, Page page) {
        List<Map<String, Object>> result = new ArrayList<>();
        SearchHits hits = response.getHits();
        for (SearchHit hit : hits.getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            for (Map.Entry<String, HighlightField> field : hit.getHighlightFields().entrySet()) {
                // 新增高亮字段返回
                sourceAsMap.put("hit_" + field.getKey(), Stream.of(field.getValue().fragments())
                        .map(Text::toString).collect(Collectors.joining()));
            }
            result.add(sourceAsMap);
        }
        page.setTotal(hits.getTotalHits().value);
        page.setRecords(result);
        return page;
    }
}
